﻿using NewsReader.Log;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.ApplicationModel.Core;
using Windows.Networking.Connectivity;
using Windows.UI.Core;

namespace NewsReader.ViewModels
{
    public static class ViewModelHelper
    {
        public static bool IsConnected
        {
            get { return NetworkInformation.GetInternetConnectionProfile() != null; }
        }

        public static bool ViewModelPropertyChanged<T>(
            this INotifyPropertyChanged viewModel,
            string propName,
            T newValue,
            ref T existingValue,
            PropertyChangedEventHandler handler) 
        {
            if (existingValue == null)
            {
                if (newValue == null)
                {
                    return false;
                }
            }
            else if (existingValue.Equals(newValue))
            {
                return false;
            }

            existingValue = newValue;
            RaisePropertyChanged(viewModel, handler, propName);
            return true;
        }

        public static void RaisePropertyChanged(this INotifyPropertyChanged viewModel, PropertyChangedEventHandler handler, string propName)
        {
            if (handler == null)
                return;

            RunActionOnGUIThread(() => handler(viewModel, new PropertyChangedEventArgs(propName)));
        }

        public static async void RunActionOnGUIThread(Action act)
        {
            try
            {
                var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
                await dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    new DispatchedHandler(act));
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("{0}", ex);
            }
        }
    }

    public class DelegateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        private readonly Action<object> _execute;
        private readonly Func<object, bool> _canExecute;

        public DelegateCommand(Action<object> execute)
            : this(execute, null)
        {
        }

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public void RaiseCanExecuteChanged()
        {
            var tmp = CanExecuteChanged;
            if (tmp != null)
            {
                tmp(this, EventArgs.Empty);
            }
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }
            else
            {
                return _canExecute(parameter);
            }
        }
        
        public void Execute(object parameter)
        {
            if (_execute != null)
            {
                _execute(parameter);
            }
        }
    }
}
